package algorthm.systemTraning.greedyAlgorithm;

import org.apache.commons.codec.DecoderException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Iterator;
import java.util.Map;
import java.util.BitSet;

/**
 * @className: HuffmanDecoder
 * @Description:
 * @Author: wangyifei
 * @Date: 2024/4/17 16:15
 */
public class HuffmanEncoder {
    private static Logger logger = LoggerFactory.getLogger(HuffmanEncoder.class);

    public static Info encode(String input , Map<Character , String> mapping){
        BitSet bs = new BitSet();
        int idx = 0 ;
        for(char c : input.toCharArray()){
            String code = mapping.get(c);
            char[] charArray = code.toCharArray();
            for(int i = charArray.length - 1 ; i >= 0 ; i-- ){
                bs.set(idx++ , charArray[i] == '1');
            }
        }
        Iterator<Map.Entry<Character, String>> iterator = mapping.entrySet().iterator();
        int max = 0 ;
        while (iterator.hasNext()) {
            Map.Entry<Character, String> next = iterator.next();
            if(max < next.getValue().length()){
                max = next.getValue().length();
            }
        }
        for (int i = 0; i < max+1; i++) {
            bs.set(idx++ , true);
        }
        return new Info(max+1 , bs) ;
    }
    public static class Info{
        public int max ;
        public BitSet bs ;
        public Info(int m , BitSet b){
            max = m ;
            bs = b ;
        }
    }

    public static byte[] encode1(String input , Map<Character , String> mapping) throws DecoderException {
        byte[] bytes = new byte[input.length()];
        int position = 0 ;
        int div = input.length()/7;
        int idx = 0 ;
        int start = 0 ;
        StringBuilder sb = new StringBuilder();
        for (char c : input.toCharArray()) {
            sb.append(mapping.get(c));
        }
        String s = sb.toString();
        int dv = s.length()/7 ;
        int md = s.length()%7 ;
        int i = 0 ;
        for (; i < div; i ++) {
            bytes[i] = Byte.decode(s.substring(i*7 , i*7 + 7)).byteValue();
        }
        if(md > 0){
            bytes[i] = (byte)(Byte.decode(s.substring(i*7)) <<(7 - md));
        }
        return bytes;
    }
}
